﻿using System.Windows;
using System.Windows.Controls;

namespace SHomeWorkshop.LunarPresentation.Commands
{
    public partial class Command
    {
        /// <summary>
        /// 在当前公式下侧插入一个文本块，并进入编辑状态。
        /// </summary>
        public static void InsertAtNextAndEditBaseText(string newText = null)
        {
            //先看看是不是插入新叶。
            if (Globals.selectedEditor != null &&
                Globals.selectedEditor.SelectedExpression != null &&
                Globals.selectedEditor.SelectedExpression is Expressions.LeafPanel)
            {
                Expressions.LeafPanel newLeaf = Command.InsertSameLevelLeaf();
                if (newLeaf != null)
                {
                    Command.EditFstBaseText();
                    Globals.selectedEditor.SelectedExpression = newLeaf;
                }
                return;
            }

            ModifingItem mi = new ModifingItem();

            LunarPresentation.Expressions.BaseText btx = Command.InsertBaseText(true, mi);
            if (btx != null)
            {
                int newIndex = btx.ParentPanel.BasePanel.Children.IndexOf(btx);

                Action actionInsert = new Action(btx.ExID, btx.ParentPanel.BasePanel.Children.IndexOf(btx),
                       btx.GetType().Name, "InsertExpression", null, btx.XmlData.OuterXml,
                       ActionType.Insert, btx.ParentPanel.ExID);
                mi.Add(actionInsert);

                RefreshHeaderLevel(mi, btx);

                //承上一个文本块的“任务列表项”属性。但只显示为“未开始”。
                if (newIndex > 0 && btx.ParentPanel != null)
                {
                    Expressions.Expression preEx = btx.ParentPanel.BasePanel.Children[newIndex - 1] as Expressions.Expression;

                    if (preEx is Expressions.BaseText && preEx.Visibility == Visibility.Visible)
                    {
                        Expressions.BaseText btOld = preEx as Expressions.BaseText;

                        if (btOld.TaskItemType != Expressions.BaseText.TaskType.NotTask)
                        {
                            Action actTaskItemType = new Action(btx.ExID, -1, btx.GetType().Name,
                                "TaskItemType", btx.TaskItemType.ToString(),
                                Expressions.BaseText.TaskType.NotStarted.ToString());

                            btx.TaskItemType = Expressions.BaseText.TaskType.NotStarted;

                            mi.Add(actTaskItemType);
                        }
                    }
                }

                //这句用于刷新界面上一些按钮的状态。
                btx.Editor.SelectedExpression = btx;

                //不重新计算就没法子自动定位
                btx.InvalidateArrange();
                btx.UpdateLayout();
                Command.EditBaseText(btx, mi, newText: newText);
            }
        }

        /// <summary>
        /// 从“上一个”或“下一个”同类文本块获取标题等级等信息并作用于当前文本块。
        /// 只有处理“Ｉ”键（向前插入一个文本块并编辑）功能时才需要使用参数“toPreview”，
        /// 这个参数的意思就是从“上一个”文本块获取格式。如果此参数值为false，则表示是从
        /// “下一个”文本块获取格式。
        /// </summary>
        /// <param name="mi"></param>
        /// <param name="btx">当前新插入的文本块。</param>
        /// <param name="toPreview">是否从“上一个”文本块获取信息。默认为true。为false时，
        /// 表示从“下一个”文本块获取格式。</param>
        /// <returns></returns>
        private static bool RefreshHeaderLevel(ModifingItem mi,
            LunarPresentation.Expressions.BaseText btx,
            bool toPreview = true)
        {
            Expressions.BaseText brotherBt;

            if (toPreview)
            {
                brotherBt = Expressions.BaseText.GetPreviewSameHeadLevelBaseText(btx);
            }
            else
            {
                brotherBt = Expressions.BaseText.GetNextSameHeadLevelBaseText(btx);
            }

            if (brotherBt != null)
            {
                Action actFontSizeLevel = new Action(btx.ExID, -1, btx.GetType().Name,
                    "FontSizeLevel", btx.FontSizeLevel.ToString(),
                    brotherBt.FontSizeLevel.ToString());
                btx.FontSizeLevel = brotherBt.FontSizeLevel;

                mi.Add(actFontSizeLevel);

                if (btx.FontWeight != brotherBt.FontWeight)
                {
                    Action actFontWeight = new Action(btx.ExID, -1, btx.GetType().Name,
                        "FontWeight", btx.FontWeight.ToString(),
                        brotherBt.FontWeight.ToString());
                    btx.FontWeight = brotherBt.FontWeight;

                    mi.Add(actFontWeight);
                }

                Action actIsHeaderText = new Action(btx.ExID, -1, btx.GetType().Name,
                    "IsHeaderText", btx.IsHeaderText.ToString(),
                    brotherBt.IsHeaderText.ToString());
                btx.IsHeaderText = brotherBt.IsHeaderText;

                mi.Add(actIsHeaderText);

                btx.ParentPanel.RefreshAutoNumbersOfBaseText();
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 在当前公式上侧插入一个文本块，缩进级别与当前公式相同。
        /// </summary>
        public static void InsertBaseAtPreviewOfSelectionAndEdit()
        {
            if (Globals.selectedEditor == null ||
                   Globals.selectedEditor.SelectedExpression == null ||
                   Globals.selectedEditor.SelectedExpression is Expressions.SubPanel)
                return;

            ModifingItem mi = new ModifingItem();

            LunarPresentation.Expressions.BaseText btx = Command.InsertBaseText(false, mi);
            if (btx != null)
            {
                int newIndex = btx.ParentPanel.BasePanel.Children.IndexOf(btx);

                Action actionInsert = new Action(btx.ExID, btx.ParentPanel.BasePanel.Children.IndexOf(btx),
                       btx.GetType().Name, "InsertExpression", null, btx.XmlData.OuterXml,
                       ActionType.Insert, btx.ParentPanel.ExID);
                mi.Add(actionInsert);

                RefreshHeaderLevel(mi, btx, false);

                //承上一个文本块的“任务列表项”属性。但只显示为“未开始”。
                if (btx.ParentPanel != null && newIndex < btx.ParentPanel.BasePanel.Children.Count - 1)
                {
                    Expressions.Expression nextEx = btx.ParentPanel.BasePanel.Children[newIndex + 1] as Expressions.Expression;

                    if (nextEx is Expressions.BaseText && nextEx.Visibility == Visibility.Visible)
                    {
                        Expressions.BaseText btOld = nextEx as Expressions.BaseText;

                        if (btOld.TaskItemType != Expressions.BaseText.TaskType.NotTask)
                        {
                            Action actTaskItemType = new Action(btx.ExID, -1, btx.GetType().Name,
                                "TaskItemType", btx.TaskItemType.ToString(),
                                Expressions.BaseText.TaskType.NotStarted.ToString());

                            btx.TaskItemType = Expressions.BaseText.TaskType.NotStarted;

                            mi.Add(actTaskItemType);
                        }
                    }
                }

                //这句用于刷新界面上一些按钮的状态。
                btx.Editor.SelectedExpression = btx;

                //不重新计算就没法子自动定位
                btx.InvalidateArrange();
                btx.UpdateLayout();
                Command.EditBaseText(btx, mi);
            }
        }

        /// <summary>
        /// 在当前公式左下侧插入一个文本块，如果当前公式左缩进为零，此功能与
        /// “插入文本块并编辑”相同。
        /// </summary>
        public static void InsertBaseAtLeftBottomOfSelectionAndEdit()
        {
            if (Globals.selectedEditor == null ||
                Globals.selectedEditor.SelectedExpression == null ||
                Globals.selectedEditor.SelectedExpression is Expressions.SubPanel)
                return;

            if (Globals.selectedEditor.SelectedExpression.ParentPanel == null) return;

            if (Globals.selectedEditor.SelectedExpression.ParentPanel.Direction !=
                System.Windows.Controls.Orientation.Vertical)
            {
                InsertBaseAtPreviewOfSelectionAndEdit();
                return;//横向子面板与向前插入等同。
            }

            ModifingItem mi = new ModifingItem();

            LunarPresentation.Expressions.BaseText btx = Command.InsertBaseText(true, mi);
            if (btx != null)
            {
                Action actionInsert = new Action(btx.ExID, btx.ParentPanel.BasePanel.Children.IndexOf(btx),
                    btx.GetType().Name, "InsertExpression", null, btx.XmlData.OuterXml,
                    ActionType.Insert, btx.ParentPanel.ExID);
                mi.Add(actionInsert);

                if (Globals.selectedEditor.SelectedExpression.Indent > 0)
                {
                    Action action = new Action(btx.ExID, -1, btx.GetType().Name, "Indent", btx.Indent.ToString(),
                        (Globals.selectedEditor.SelectedExpression.Indent - 1).ToString());

                    btx.Indent = Globals.selectedEditor.SelectedExpression.Indent - 1;

                    mi.Add(action);
                }

                if (btx.ParentPanel.Direction == Orientation.Vertical)
                {
                    if (RefreshHeaderLevel(mi, btx) == false)
                    {
                        RefreshHeaderLevelElseLeftBottom(mi, btx);
                    }
                }

                //这句用于刷新界面上一些按钮的状态。
                btx.Editor.SelectedExpression = btx;

                //不重新计算就没法子自动定位
                btx.InvalidateArrange();
                btx.UpdateLayout();
                Command.EditBaseText(btx, mi);
            }
        }

        private static void RefreshHeaderLevelElseLeftBottom(ModifingItem mi, LunarPresentation.Expressions.BaseText btx)
        {
            RefreshHeaderLevelElsePre(mi, btx);

            if (btx.FontSizeLevel <= 4 && btx.FontSizeLevel > 0)
            {
                Action actFontSizelevel = new Action(btx.ExID, -1, btx.GetType().Name,
                    "FontSizeLevel", btx.FontSizeLevel.ToString(),
                    (btx.FontSizeLevel + 1).ToString());
                btx.FontSizeLevel++;

                mi.Add(actFontSizelevel);

                if (btx.FontSizeLevel == 4)
                {
                    if (btx.FontWeight != FontWeights.Bold)
                    {
                        Action actFontWeight = new Action(btx.ExID, -1, btx.GetType().Name,
                        "FontWeight", btx.FontWeight.ToString(),
                        FontWeights.Bold.ToString());
                        btx.FontWeight = FontWeights.Bold;

                        mi.Add(actFontWeight);
                    }
                }
                else
                {
                    if (btx.FontWeight != FontWeights.Normal)
                    {
                        Action actFontWeight = new Action(btx.ExID, -1, btx.GetType().Name,
                        "FontWeight", btx.FontWeight.ToString(),
                        FontWeights.Normal.ToString());
                        btx.FontWeight = FontWeights.Normal;

                        mi.Add(actFontWeight);
                    }
                }
            }
            else
            {
                if (btx.FontWeight != FontWeights.Normal)
                {
                    Action actFontWeight = new Action(btx.ExID, -1, btx.GetType().Name,
                    "FontWeight", btx.FontWeight.ToString(),
                    FontWeights.Normal.ToString());
                    btx.FontWeight = FontWeights.Normal;

                    mi.Add(actFontWeight);
                }

                if (btx.FontSizeLevel == 0)
                {
                    if (btx.Indent == 3)//进入４级标题。
                    {
                        Action actFontSizelevel = new Action(btx.ExID, -1, btx.GetType().Name,
                        "FontSizeLevel", btx.FontSizeLevel.ToString(), "1");
                        btx.FontSizeLevel = 1;
                        if (btx.ParentPanel != null)
                        {
                            btx.ParentPanel.RefreshAutoNumbersOfBaseText();
                        }

                        mi.Add(actFontSizelevel);
                    }
                }
            }

            btx.ParentPanel.RefreshAutoNumbersOfBaseText();
        }

        /// <summary>
        /// 在当前公式右下侧插入一个文本块，如果当前公式左缩进值已为最大，此功能与
        /// “插入文本块并编辑”相同。
        /// </summary>
        public static void InsertBaseAtRightBottomOfSelectionAndEdit()
        {
            if (Globals.selectedEditor == null ||
                Globals.selectedEditor.SelectedExpression == null ||
                Globals.selectedEditor.SelectedExpression is Expressions.SubPanel)
                return;

            if (Globals.selectedEditor.SelectedExpression.ParentPanel == null) return;

            if (Globals.selectedEditor.SelectedExpression.ParentPanel.Direction !=
                System.Windows.Controls.Orientation.Vertical)
            {
                InsertAtNextAndEditBaseText();
                return;//横向子面板中与“向后插入”等同。
            }

            ModifingItem mi = new ModifingItem() { OldSelectedExID = Globals.selectedEditor.SelectedExpression.ExID };

            LunarPresentation.Expressions.BaseText btx = Command.InsertBaseText(true, mi);

            if (btx != null)
            {
                Action actionInsert = new Action(btx.ExID, btx.ParentPanel.BasePanel.Children.IndexOf(btx),
                    btx.GetType().Name, "InsertExpression", null, btx.XmlData.OuterXml,
                    ActionType.Insert, btx.ParentPanel.ExID);
                mi.Add(actionInsert);

                if (Globals.selectedEditor.SelectedExpression.Indent < 6)
                {
                    Action action = new Action(btx.ExID, -1, btx.GetType().Name, "Indent", btx.Indent.ToString(),
                        (Globals.selectedEditor.SelectedExpression.Indent + 1).ToString());

                    btx.Indent = Globals.selectedEditor.SelectedExpression.Indent + 1;

                    mi.Add(action);

                    if (btx.ParentPanel.Direction == Orientation.Vertical)
                    {
                        if (RefreshHeaderLevel(mi, btx) == false)
                        {
                            RefreshHeaderLevelElseRightBottom(mi, btx);
                        }
                    }
                }

                //这句用于刷新界面上一些按钮的状态。
                btx.Editor.SelectedExpression = btx;

                //寻找上一个‘可见公式’，如果此可见公式是个标题文本块，
                //且已被折叠，则展开之。
                int index = btx.ParentPanel.BasePanel.Children.IndexOf(btx);
                Expressions.BaseText preVisiableHeaderText = null;
                for (int i = index - 1; i >= 0; i--)
                {
                    Expressions.Expression ex = btx.ParentPanel.BasePanel.Children[i] as Expressions.Expression;
                    if (ex.Visibility == Visibility.Visible)
                    {
                        if (ex is Expressions.BaseText)
                        {
                            Expressions.BaseText preBt = ex as Expressions.BaseText;
                            if (preBt.IsHeaderText && preBt.IsCollapsed)
                            {
                                preVisiableHeaderText = preBt;
                                break;
                            }
                            else break;
                        }
                        else break;
                    }
                    else continue;
                }

                if (preVisiableHeaderText != null)
                {
                    if (preVisiableHeaderText.IsCollapsed)
                    {
                        Action actCollapsed = new Action(preVisiableHeaderText.ExID,
                            -1, preVisiableHeaderText.GetType().Name, "IsCollapsed",
                            preVisiableHeaderText.IsCollapsed.ToString(),
                            false.ToString());

                        preVisiableHeaderText.IsCollapsed = false;

                        mi.Add(actCollapsed);
                    }
                }

                //不重新计算就没法子自动定位
                btx.InvalidateArrange();
                btx.UpdateLayout();
                Command.EditBaseText(btx, mi);
            }
        }

        /// <summary>
        /// 这个功能只有（插入到左下和插入到右下两个动作会调用）。
        /// 判断btx上面一个公式是什么类型，如果是文本块，先取其部分属性。
        /// </summary>
        /// <param name="mi"></param>
        /// <param name="btx"></param>
        private static void RefreshHeaderLevelElsePre(ModifingItem mi,
            LunarPresentation.Expressions.BaseText btx)
        {
            if (btx.ParentPanel == null ||
                btx.ParentPanel.Direction == Orientation.Horizontal)
                return;

            if (btx.ParentPanel.BasePanel.Children.Contains(btx) == false) return;

            int index = btx.ParentPanel.BasePanel.Children.IndexOf(btx);
            if (index <= 0) return;

            if (btx.ParentPanel.BasePanel.Children[index - 1] is Expressions.BaseText == false) return;

            Expressions.BaseText preBt = btx.ParentPanel.BasePanel.Children[index - 1] as Expressions.BaseText;

            Action actFontSizelevel = new Action(btx.ExID, -1, btx.GetType().Name,
                    "FontSizeLevel", btx.FontSizeLevel.ToString(),
                    preBt.FontSizeLevel.ToString());
            btx.FontSizeLevel = preBt.FontSizeLevel;

            mi.Add(actFontSizelevel);

            Action actFontWeight = new Action(btx.ExID, -1, btx.GetType().Name,
                        "FontWeight", btx.FontWeight.ToString(),
                        preBt.FontWeight.ToString());
            btx.FontWeight = preBt.FontWeight;

            mi.Add(actFontWeight);

            Action actIsHeaderText = new Action(btx.ExID, -1, btx.GetType().Name,
                "IsHeaderText", btx.IsHeaderText.ToString(),
                preBt.IsHeaderText.ToString());
            btx.IsHeaderText = preBt.IsHeaderText;

            mi.Add(actIsHeaderText);
        }

        private static void RefreshHeaderLevelElseRightBottom(ModifingItem mi,
            LunarPresentation.Expressions.BaseText btx)
        {
            RefreshHeaderLevelElsePre(mi, btx);

            if (btx.FontSizeLevel <= 4 && btx.FontSizeLevel > 0)
            {
                Action actFontSizelevel = new Action(btx.ExID, -1, btx.GetType().Name,
                    "FontSizeLevel", btx.FontSizeLevel.ToString(),
                    (btx.FontSizeLevel - 1).ToString());
                btx.FontSizeLevel--;

                mi.Add(actFontSizelevel);

                //if (btx.FontSizeLevel % 2 == 0 && btx.FontSizeLevel > 0)
                if (btx.FontSizeLevel == 4)
                {
                    if (btx.FontWeight != FontWeights.Bold)
                    {
                        Action actFontWeight = new Action(btx.ExID, -1, btx.GetType().Name,
                        "FontWeight", btx.FontWeight.ToString(),
                        FontWeights.Bold.ToString());
                        btx.FontWeight = FontWeights.Bold;

                        mi.Add(actFontWeight);
                    }
                }
                else
                {
                    if (btx.FontWeight != FontWeights.Normal)
                    {
                        Action actFontWeight = new Action(btx.ExID, -1, btx.GetType().Name,
                        "FontWeight", btx.FontWeight.ToString(),
                        FontWeights.Normal.ToString());
                        btx.FontWeight = FontWeights.Normal;

                        mi.Add(actFontWeight);
                    }
                }
            }
            else
            {
                if (btx.FontWeight != FontWeights.Normal)
                {
                    Action actFontWeight = new Action(btx.ExID, -1, btx.GetType().Name,
                    "FontWeight", btx.FontWeight.ToString(),
                    FontWeights.Normal.ToString());
                    btx.FontWeight = FontWeights.Normal;

                    mi.Add(actFontWeight);
                }
            }

            btx.ParentPanel.RefreshAutoNumbersOfBaseText();
        }


        /// <summary>
        /// 在当前公式下侧插入一个文本块，并指定其标题等级。
        /// </summary>
        public static void InsertHeaderText(int headLevel)
        {
            if (Globals.selectedEditor == null ||
                Globals.selectedEditor.SelectedExpression == null)
                return;

            Expressions.Expression curEx = Globals.selectedEditor.SelectedExpression;

            ModifingItem mi = new ModifingItem() { OldSelectedExID = curEx.ExID };

            if (curEx is Expressions.SubPanel)
            {
                Expressions.SubPanel subPanel = curEx as Expressions.SubPanel;

                if (subPanel.BasePanel.Children.Count <= 0) return;

                curEx = subPanel.BasePanel.Children[subPanel.BasePanel.Children.Count - 1] as Expressions.Expression;
            }

            if (curEx.ParentPanel.Direction != System.Windows.Controls.Orientation.Vertical)
            {
                MessageBox.Show("水平指向的子面板中不允许插入标题。",
                    Globals.appName, MessageBoxButton.OK, MessageBoxImage.Warning);
                return;
            }

            LunarPresentation.Expressions.BaseText btx = Command.InsertBaseText(true, mi);

            int indent = 0;
            if (headLevel < 1)
            {
                indent = 0;
            }
            else if (headLevel > 4)
            {
                headLevel = 3;
            }
            else
            {
                indent = headLevel - 1;
            }

            if (btx != null)
            {
                Action actionInsert = new Action(btx.ExID, btx.ParentPanel.BasePanel.Children.IndexOf(btx),
                    btx.GetType().Name, "InsertExpression", null, btx.XmlData.OuterXml,
                    ActionType.Insert, btx.ParentPanel.ExID);
                mi.Add(actionInsert);

                if (btx.Indent != indent)
                {
                    Action action = new Action(btx.ExID, -1, btx.GetType().Name, "Indent", btx.Indent.ToString(),
                        indent.ToString());

                    btx.Indent = indent;

                    mi.Add(action);
                }

                if (btx.IsHeaderText == false)
                {
                    Action actHeader = new Action(btx.ExID, -1, btx.GetType().Name, "IsHeaderText",
                        false.ToString(), true.ToString());

                    btx.IsHeaderText = true;

                    mi.Add(actHeader);
                }

                int fontSizeLevel = 4 - indent;

                if (btx.FontSizeLevel != fontSizeLevel)
                {
                    Action actFontSizeLevel = new Action(btx.ExID, -1, btx.GetType().Name, "FontSizeLevel",
                        btx.FontSizeLevel.ToString(), fontSizeLevel.ToString());

                    btx.FontSizeLevel = fontSizeLevel;

                    mi.Add(actFontSizeLevel);
                }

                if (indent == 0)//一、级标题要加粗。
                {
                    if (btx.FontWeight != FontWeights.Bold)
                    {
                        Action actBold = new Action(btx.ExID, -1, btx.GetType().Name, "FontWeight",
                            btx.FontWeight.ToString(), FontWeights.Bold.ToString());

                        btx.FontWeight = FontWeights.Bold;

                        mi.Add(actBold);
                    }
                }

                btx.ParentPanel.RefreshAutoNumbersOfBaseText();

                //这句用于刷新界面上一些按钮的状态。
                btx.Editor.SelectedExpression = btx;

                //不重新计算就没法子自动定位
                btx.InvalidateArrange();
                btx.UpdateLayout();
                Command.EditBaseText(btx, mi);
            }
        }
    }
}
